﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Diagnostics;

namespace System.Peppers.Wmi
{
    /// <summary>
    /// The Win32_ProcessStartup abstract WMI class represents the startup configuration of a Windows-based process. The class is defined as a method type definition, which means that it is only used for passing information to the Create method of the Win32_Process class.
    /// </summary>
    public sealed class ProcessStartup : WmiWrapper
    {
        #region Static
        private static class WmiProperties
        {
            public const string CreateFlags = "CreateFlags",
                EnvironmentVariables = "EnvironmentVariables",
                ErrorMode = "ErrorMode",
                FillAttribute = "FillAttribute",
                PriorityClass = "PriorityClass",
                ShowWindow = "ShowWindow",
                Title = "Title",
                WinstationDesktop = "WinstationDesktop",
                X = "X",
                XCountChars = "XCountChars",
                XSize = "XSize",
                Y = "Y",
                YCountChars = "YCountChars",
                YSize = "YSize";
        }
        #endregion

        /// <summary>
        /// Creates a new instance
        /// </summary>
        public ProcessStartup()
            : base(new ManagementObject(WmiClasses.Win32_ProcessStartup))
        { }

        /// <summary>
        /// Additional values that control the priority class and the creation of the process. The following creation values can be specified in any combination, except as noted.
        /// </summary>
        public ProcessCreateFlags CreateFlags
        {
            get { return (ProcessCreateFlags)Convert.ToUInt32(this[WmiProperties.CreateFlags] ?? 0); }
        }

        /// <summary>
        /// List of settings for the configuration of a computer. Environment variables specify search paths for files, directories for temporary files, application-specific options, and other similar information. The system maintains a block of environment settings for each user and one for the computer. The system environment block represents environment variables for all of the users of a specific computer. A user's environment block represents the environment variables that the system maintains for a specific user, and includes the set of system environment variables. By default, each process receives a copy of the environment block for its parent process. Typically, this is the environment block for the user who is logged on. A process can specify different environment blocks for its child processes.
        /// </summary>
        public string[] EnvironmentVariables
        {
            get { return this[WmiProperties.EnvironmentVariables] as string[]; }
            set { this[WmiProperties.EnvironmentVariables] = value; }
        }

        /// <summary>
        /// On some non-x86 processors, misaligned memory references cause an alignment fault exception. The No_Alignment_Fault_Except flag lets you control whether or not an operating system automatically fixes such alignment faults, or makes them visible to an application. On a millions of instructions per second (MIPS) platform, an application must explicitly call SetErrorMode with the No_Alignment_Fault_Except flag to have the operating system automatically fix alignment faults.  How an operating system processes several types of serious errors. You can specify that the operating system process errors, or an application can receive and process errors.  The default setting is for the operating system to make alignment faults visible to an application. Because the x86 platform does not make alignment faults visible to an application, the No_Alignment_Fault_Except flag does not make the operating system raise an alignment fault error—even if the flag is not set. The default state for SetErrorMode is to set all of the flags to 0 (zero).
        /// </summary>
        public ProcessErrorMode ErrorMode
        {
            get { return (ProcessErrorMode)Convert.ToUInt32(this[WmiProperties.ErrorMode] ?? 0); }
            set { this[WmiProperties.ErrorMode] = value; }
        }

        /// <summary>
        /// The text and background colors if a new console window is created in a console application. These values are ignored in graphical user interface (GUI) applications.
        /// </summary>
        public ProcessFill FillAttribute
        {
            get { return (ProcessFill)Convert.ToUInt32(this[WmiProperties.FillAttribute] ?? 0); }
            set { this[WmiProperties.FillAttribute] = value; }
        }
        
        /// <summary>
        /// Priority class of the new process. Use this property to determine the schedule priorities of the threads in the process. If the property is left null, the priority class defaults to Normal—unless the priority class of the creating process is Idle or Below_Normal. In these cases, the child process receives the default priority class of the calling process.
        /// </summary>
        public ProcessPriorityClass PriorityClass
        {
            get { return (ProcessPriorityClass)Convert.ToUInt32(this[WmiProperties.PriorityClass] ?? 0); }
            set { this[WmiProperties.PriorityClass] = value; }
        }

        /// <summary>
        /// How the window is displayed to the user.
        /// </summary>
        public WindowStyle WindowStyle
        {
            get { return (WindowStyle)Convert.ToUInt32(this[WmiProperties.ShowWindow] ?? 0); }
            set { this[WmiProperties.ShowWindow] = value; }
        }

        /// <summary>
        /// Text displayed in the title bar when a new console window is created; used for console processes. If NULL, the name of the executable file is used as the window title. This property must be NULL for GUI or console processes that do not create a new console window.
        /// </summary>
        public string Title
        {
            get { return Convert.ToString(this[WmiProperties.Title]); }
            set { this[WmiProperties.Title] = value; }
        }

        /// <summary>
        /// The name of the desktop or the name of both the desktop and window station for the process—for Windows NT only. A backslash in the string indicates that the string includes both desktop and window station names. If WinstationDesktop is NULL, the new process inherits the desktop and window station of its parent process. If WinstationDesktop is an empty string, the process does not inherit the desktop and window station of its parent process. The system determines if a new desktop and window station must be created. A window station is a secure object that contains a clipboard, a set of global atoms, and a group of desktop objects. The interactive window station that is assigned to the logon session of the interactive user also contains the keyboard, mouse, and display device. A desktop is a secure object contained within a window station. A desktop has a logical display surface and contains windows, menus, and hooks. A window station can have multiple desktops. Only the desktops of the interactive window station can be visible and receive user input.
        /// </summary>
        public string WinstationDesktop
        {
            get { return Convert.ToString(this[WmiProperties.WinstationDesktop]); }
            set { this[WmiProperties.WinstationDesktop] = value; }
        }

        /// <summary>
        /// The X offset of the upper left corner of a window if a new window is created—in pixels. The offsets are from the upper left corner of the screen. For GUI processes, the specified position is used the first time the new process calls CreateWindow to create an overlapped window if the X parameter of CreateWindow is CW_USEDEFAULT.  Note  X and Y cannot be specified independently.
        /// </summary>
        public uint X
        {
            get { return Convert.ToUInt32(this[WmiProperties.X] ?? 0); }
            set { this[WmiProperties.X] = value; }
        }

        /// <summary>
        /// Screen buffer width in character columns. This property is used for processes that create a console window, and is ignored in GUI processes.  Note  XCountChars and YCountChars cannot be specified independently.
        /// </summary>
        public uint XCountChars
        {
            get { return Convert.ToUInt32(this[WmiProperties.XCountChars] ?? 0); }
            set { this[WmiProperties.XCountChars] = value; }
        }

        /// <summary>
        /// Pixel width of a window if a new window is created. For GUI processes, this is only usedthe first time the new process calls CreateWindow to create an overlapped window if the nWidth parameter of CreateWindow is CW_USEDEFAULT.  Note  XSize and YSize cannot be specified independently.
        /// </summary>
        public uint XSize
        {
            get { return Convert.ToUInt32(this[WmiProperties.XSize] ?? 0); }
            set { this[WmiProperties.XSize] = value; }
        }

        /// <summary>
        /// Pixel offset of the upper-left corner of a window if a new window is created. The offsets are from the upper-left corner of the screen. For GUI processes, the specified position is used the first time the new process calls CreateWindow to create an overlapped window if the y parameter of CreateWindow is CW_USEDEFAULT.  Note  X and Y cannot be specified independently.
        /// </summary>
        public uint Y
        {
            get { return Convert.ToUInt32(this[WmiProperties.Y] ?? 0); }
            set { this[WmiProperties.Y] = value; }
        }

        /// <summary>
        /// Screen buffer height in character rows. This property is used for processes that create a console window, but is ignored in GUI processes.  Note  XCountChars and YCountChars cannot be specified independently.
        /// </summary>
        public uint YCountChars
        {
            get { return Convert.ToUInt32(this[WmiProperties.YCountChars] ?? 0); }
            set { this[WmiProperties.YCountChars] = value; }
        }

        /// <summary>
        /// Pixel height of a window if a new window is created. For GUI processes, this is used only the first time the new process calls CreateWindow to create an overlapped window if the nWidth parameter of CreateWindow is CW_USEDEFAULT.  Note  XSize and YSize cannot be specified independently.
        /// </summary>
        public uint YSize
        {
            get { return Convert.ToUInt32(this[WmiProperties.YSize] ?? 0); }
            set { this[WmiProperties.YSize] = value; }
        }
    }
}
